package com.wholeintech.ble;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;

import com.wholeintech.utils.CommonUtil;
import com.wholeintech.entity.DeviceDb;

import org.xutils.DbManager;
import org.xutils.ex.DbException;

import java.util.ArrayList;
import java.util.Vector;

import static com.wholeintech.ble.Utils.logPrint;
import static com.wholeintech.utils.CommonIntent.ACTION_INFO_RETURN;

/**
 * Created by Lyle on 2016-03-12.
 */
public class DeviceList {

    private final static String TAG = "BLE_DevList";

    private final static String ACTION_BLE_ADD = "com.wit.device.add";
    private final static String ACTION_BLE_DELETE = "com.wit.device.remove";
    private final static String ACTION_BLE_SHOWQRCODE = "com.wit.connect.showQRcode";
    //private final static String ACTION_BLE_GETSTATE = "com.wholeintech.lyle.BleServer.getstate";

    public static final int TYPE_MASTERBOX = 1000;//
    public static final int TYPE_TOPBOX = 1010;//
    public static final int TYPE_SWITCH = 1020;//
    public static final int TYPE_LIGHT = 1030;//
    public static final int TYPE_LIGHT_DIMMER = 1031;//
    public static final int TYPE_CURTAIN = 1040;//
    public final static int TYPE_AIRCON = 1050;//
    public final static int TYPE_FLOOR_HEATING = 1060;//
    public final static int TYPE_FRESH_AIR = 1070;//
    public final static int TYPE_JBY = 1080;//
    public final static int TYPE_DOOR_SENSOR = 1090;//
    public final static int DEV_TYPE_AIR_CLEANER = 1100;//
    public final static int TYPE_PROJECT = 1110;
    public final static int TYPE_INFRARED = 1120;//zigbee
    public final static int TYPE_AIR_RADIO = 1130;//
    public final static int TYPE_SHOCK_SENSOR = 1140;//

    public static final int BLE_NETWORK = 2;
    public static final int ETHERNET_NETWORK = 3;
    public static final int WIFI_NETWORK = 4;

    private ArrayList<String> mListMacAndState;

    Vector<DevInfoItem> mDevInfoItem;

    private static DeviceList mDeviceList;

    private BleService mService;

    private Context mContext;

    private DeviceList() {
    }

    private DeviceList(Context c) {
        mContext = c;
        mListMacAndState = new ArrayList<String>();

        mDevInfoItem = new Vector<DevInfoItem>();

        IntentFilter mFilter = new IntentFilter();
        mFilter.addAction(ACTION_BLE_ADD);
        mFilter.addAction(ACTION_BLE_DELETE);

        //mFilter.addAction(ACTION_BLE_GETSTATE);
        mContext.registerReceiver(mReceiver, mFilter);

        Intent bindIntent = new Intent(mContext, BleService.class);
        mContext.bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
    }

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder rawBinder) {
            mService = ((BleService.LocalBinder) rawBinder).getService();
        }

        public void onServiceDisconnected(ComponentName classname) {
            ////     mService.disconnect(mDevice);
            mService = null;

            Log.e(TAG, "Bind service fail!");
        }
    };

    public static DeviceList getInstance(Context c) {

        if (mDeviceList == null) {
            mDeviceList = new DeviceList(c);
        }
        return mDeviceList;
    }

    /*public void addToDevList() {

        DbUtils db = CommonUtil.MyDbUtils(mContext);
        try {

            List<DeviceDb> listBleDb = db.findAll(DeviceDb.class);
            if(listBleDb == null) {
                logPrint(TAG, "Not Device add to list!");
                return;
            }

            for (final DeviceDb item :listBleDb) {

                if (item.getType() == TYPE_DOOR_SENSOR) {
                    if (item.getAsMag()==1)
                        mListMacAndState.add(item.getMacAddr() + "1");
                    else
                        mListMacAndState.add(item.getMacAddr() + "0");
                } else if (item.getType() == TYPE_TOPBOX) {

                    DevInfoItem mDev = new DevInfoItem(item.getDevId(),item.getType(),item.getMacAddr(),null);
                    mDevInfoItem.add(mDev);
                    //mListTopBoxMac.add(item.getDevMAC());
                }
            }
        } catch (DbException e) {
            e.printStackTrace();
        }
    }*/


    public boolean addNewDev(int deviceType, String boxId, String devId, String mac, String name) {

        DbManager db = CommonUtil.MyDbUtils();
        try {

            DeviceDb ZBData = new DeviceDb(boxId, devId, name, DeviceList.BLE_NETWORK, deviceType, mac, -1);

//            DeviceDb me = db.findFirst(Selector.from(DeviceDb.class).where("devId", "=", devId));
            DeviceDb me = db.selector(DeviceDb.class).where("devId", "=", devId).findFirst();
            if (me == null) {
                db.save(ZBData);
            } else {
                Log.e(TAG, "This device registered,devID:" + devId);
                intentRsp(ACTION_BLE_ADD, 1);
                return false;
            }

        } catch (DbException | NumberFormatException e) {
            e.printStackTrace();
            return false;
        }
        intentRsp(ACTION_BLE_ADD, 0);
        DevInfoItem mDev = new DevInfoItem(devId, deviceType, mac, null);
        mDevInfoItem.add(mDev);
        return true;
    }

    public boolean deleteDev(String devId) {

        DbManager db = CommonUtil.MyDbUtils();
        try {

//            DeviceDb me = db.findFirst(Selector.from(DeviceDb.class).where("devId", "=", devId));
            DeviceDb me = db.selector(DeviceDb.class).where("devId", "=", devId).findFirst();

            if (me != null) {

                db.delete(me);
                db.saveOrUpdate(me);
                logPrint(TAG, "Delete devId:" + devId + "sucessful");
                return true;
            } else {
                Log.e(TAG, "Delete: Not found, devId:" + devId);
            }

        } catch (DbException | NumberFormatException e) {

            e.printStackTrace();
            return false;
        }
        return false;
    }

    public void findToxBoxAddr(String address) {

        for (int i = 0; i < mDeviceList.mDevInfoItem.size(); i++) {
            if (address.equals(mDeviceList.mDevInfoItem.get(i).getDevMAC())) {
                if (mService != null) {
                    Log.e(TAG, "Connect:" + address);

                    //mService.connect(address);
                    // mService.scanLeDevice(true);
                }
                break;
            }
        }
    }

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub

            if (intent.getAction().equals(ACTION_BLE_ADD)) {
                Log.e(TAG, "ACTION_BLE_ADD");

                try {
                    String boxId = intent.getStringExtra("boxId");
                    int devType = intent.getIntExtra("type", 0);
                    int network = intent.getIntExtra("network", 0);
                    String devId = intent.getStringExtra("deviceId");
                    String mac = intent.getStringExtra("macAddr").toUpperCase();
                    String name = intent.getStringExtra("name");

                    if (mac.length() > 0 && network == BLE_NETWORK) {
                        // mac = mac + "-1";

                        if (devType == TYPE_DOOR_SENSOR) {

                            if ((!mListMacAndState.contains(mac + "-1")) && (!mListMacAndState.contains(mac + "+0")) && (!mListMacAndState.contains(mac + "+1"))) {

                                if (addNewDev(devType, boxId, devId, mac, name)) {
                                    mac = mac + "-1";
                                    mListMacAndState.add(mac);

                                    Log.e(TAG, "ACTION_BLE_ADD:" + mac);
                                    Log.e(TAG, "Dev List:" + mListMacAndState.toString());
                                }
                            }
                        } else {

                            if (addNewDev(devType, boxId, devId, mac, name)) {
                                Log.e(TAG, "ACTION_BLE_ADD:" + mac);
                            }
                        }
                    }


                } catch (Exception e) {
                    Log.e(TAG, "Error:" + e);
                }

            } else if (intent.getAction().equals(ACTION_BLE_DELETE)) {


                String mac = intent.getStringExtra("macAddr");
                String devId = intent.getStringExtra("deviceId");
                byte type = intent.getByteExtra("type", (byte) 0);

                if (deleteDev(devId)) {

                    mListMacAndState.remove(mListMacAndState.remove(mac + "+0"));
                    mListMacAndState.remove(mListMacAndState.remove(mac + "+1"));
                    mListMacAndState.remove(mListMacAndState.remove(mac + "-1"));
                }

                intentRsp(ACTION_BLE_DELETE);
                logPrint(TAG, "ACTION_BLE_DELETE devId:" + devId + ",MAC:" + mac);
            }/* else if (intent.getAction().equals(ACTION_BLE_GETSTATE)) {

                String mac = intent.getStringExtra("MAC");
                if (mac.length() > 0) {

                    if (mListMacAndState.indexOf(mac + "+0") != -1) {
                        sendBroadcastMsg(ACTION_BLE_GETSTATE, mac, "0");

                    } else if (mListMacAndState.indexOf(mac + "+1") != -1) {

                        sendBroadcastMsg(ACTION_BLE_GETSTATE, mac, "1");
                    }

                    Log.e(TAG, "ACTION_BLE_STATE:" + mac);
                    Log.e(TAG, "Dev List:" + mListMacAndState.toString());
                }
            }*/
        }
    };

    public void intentRsp(String intent) {
        Intent mIntent = new Intent(ACTION_INFO_RETURN);

        mIntent.putExtra("intentId", intent);
        mIntent.putExtra("return", "0");

        mContext.sendBroadcast(mIntent);
    }

    public void intentRsp(String intent, int result) {
        Intent mIntent = new Intent(ACTION_INFO_RETURN);

        mIntent.putExtra("intentId", intent);
        mIntent.putExtra("return", result);

        mContext.sendBroadcast(mIntent);
    }

    public void unregisterReceiver() {
        mContext.unregisterReceiver(mReceiver);
    }

}
